package com.owc.service;

import com.owc.common.converter.OutputConverter;
import com.owc.common.tool.BeanUtils;
import com.owc.common.tool.ReflectionUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.ParameterizedType;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author xiaom
 * @Date 2020/2/24 17:41
 * @Version 1.0.0
 * @Description <>
 **/
public interface ConverterService<DTO extends OutputConverter<DTO,DOMAIN>,DOMAIN> {

    /**
     * Model to DTO converter handler
     * @param list Models
     * @return DTO
     */
    @SuppressWarnings("unchecked")
    default List<DTO> convertTo(@Nullable List<DOMAIN> list){
        if (CollectionUtils.isEmpty(list)) {
            return Collections.emptyList();
        }

        // Get parameterized type
        ParameterizedType currentType = parameterizedType();

        // Assert not equal
        Objects.requireNonNull(currentType, "Cannot fetch actual type because parameterized type is null");

        Class<DTO> domainClass = (Class<DTO>) currentType.getActualTypeArguments()[0];

        return list.stream().map(link -> BeanUtils.transformFrom(link, domainClass))
                .collect(Collectors.toList());
    }

    /**
     * Get parameterized type.
     *
     * @return parameterized type or null
     */
    @Nullable
    default ParameterizedType parameterizedType() {
        return ReflectionUtils.getParameterizedType(ConverterService.class, this.getClass());
    }

}
